/**
 * 
 * install: vue.use()调用install时传递两个参数，1. vue的构造函数，2.可选对象
 * 
 */

let _Vue = null

export default class VueRouter {
    static install (Vue) {
        // 1.判断当前插件是否已经安装，如果已经安装就不需要重复安装 （给一个installed变量去判断是否有被注册） 
        if(VueRouter.install.installed) return  
        VueRouter.install.installed = true
        // 2.把vue构造函数记录到全局变量，install是静态方法，接收了一个vue构造函数，而在VueRouter的实例中还要使用构造函数，比如创建router-link和router-view时，需要调用vue.component来创建
        _Vue = Vue
        // 3.把创建vue实例时候传入的router对象注入到vue实例上. （可以将其放入原型中），

        //混入
        _Vue.mixin({
            //通过beforeCreate去获取this，这里的this指向的是vue实例
            beforeCreate () {
                //防止多次挂载，判断作用是只在页面才挂载，在组件便不挂载
                if(this.$options.router) {
                    //只有页面才有$options.router这个选项
                    _Vue.prototype.$router = this.$options.router
                    this.$options.router.init()

                }
            }
        })
    }

    /**
     * @param {*} options 记录Vue中传入的对象
     */
    constructor (options) {
        console.log(options,'options');
        this.options = options 
        // key：路由地址， value： 组件
        this.routeMap = {}
        //响应式对象，current记录当前路由地址
        this.data = _Vue.observable({
            current: window.location.pathname
        })
    }
    
    //将routes转换成key，value存到routeMap中
    createRouteMap () {
       for(let route of this.options.routes) {
           this.routeMap[route.path] =route.component
       }
            //遍历所有的路由规则 吧路由规则解析成键值对的形式存储到routeMap中
            // this.options.routes.forEach(route => {
            //     this.routeMap[route.path] = route.component
            // });
    }

    /**
     *  router-link, router-view 实现
     */
    initComponents (Vue) {
       const self = this
       Vue.component('router-link', {
           props: {
              to: String
           },
        //    template: `<a :href="to">
        //               <slot></slot>
        //              </a>`
           render (h) {
               /**
                * h: 帮助创建虚拟dom
                * @param {arg1, arg2, arg3} 
                * 元素选择器 
                * 设置属性， （如果是dom对象属性需要加attrs,设置事件加on）
                * 生成元素的字元素 array
                */
               return h('a', {
                   attrs: {
                       href: this.to
                   },
                   on: {
                      click: this.clickHandleer
                   }
               },
               [this.$slots.default])
           },
        //    created () {  
        //        //解决页面刷新之后路由地址没变,但是渲染的组件回到初始位置的问题
        //        if(window.location.pathname === this.to) {
        //            this.$router.data.current = this.to
        //        }
        //    },
           methods: {
            clickHandleer (e) {
               history.pushState('', '', this.to)
               this.$router.data.current = this.to
               e.preventDefault()
            }
           }

       })
       Vue.component('router-view', {
           render (h) {
               let component = self.routeMap[self.data.current]
               return h(component)
           }
       })
    }
    
    init () {
        this.createRouteMap() 
        this.initComponents(_Vue)
        this.initEvent()
    }
    

    initEvent () {
      //历史方式变化时触发
      window.addEventListener('popstate', () => {
          this.data.current = window.location.pathname
      })

    }

}